﻿using System.Text.Json.Serialization;
using System.Text.Json;
using static Sirius.Log.Log;
using System.Net.WebSockets;
using System.Text;

namespace Sirius.WebSocket
{

    public class SiriusWebSocketBase
    {
        //SiriusClient连接
        public delegate void OnConnectHandler(Object sender);
        //SiriusClient收到消息
        public delegate void OnMessageHandler(Object sender,string message);
        //SiriusClient断开连接
        public delegate void OnDisconnectHandler(Object sender);
        //发送消息
        public static void SendMsg(ClientWebSocket SiriusClient,string msg)
        {
            //判断SiriusClient是否初始化
            if (SiriusClient == null)
                LogErr("Server", "SiriusClient未初始化，请初始化后再试！");

            byte[] msgByte = Encoding.UTF8.GetBytes(msg);
            //发送消息
            var task = SiriusClient.SendAsync(new ArraySegment<byte>(msgByte), WebSocketMessageType.Binary, true, CancellationToken.None);
            task.Wait();

        }
        //接收5MB的长度消息
        public static Task Recived(ClientWebSocket SiriusClient,out string message)
        {
            if (SiriusClient == null)
                LogErr("Server", "SiriusClient未初始化，请初始化后再试！");
            //缓冲消息长度
            byte[] buffer = new byte[1024 * 1024 * 5];
            //接收消息
            var task = SiriusClient.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
            //等待接收完成
            //返回消息
            message = Encoding.UTF8.GetString(buffer.Take(task.Result.Count).ToArray());
            return task;
        }
    }

    public class SiriusWebSocketClient:SiriusWebSocketBase
    {
        //SiriusHttp客户端
        public static HttpClient SiriusHttp;
        //Sirius客户端
        public static ClientWebSocket SiriusClient;
        //用于WS连接的URI
        public static Uri url;
        //SiriusClient连接事件
        public static event OnConnectHandler OnConnect;
        //SiriusClient收到消息事件
        public static event OnMessageHandler OnMessage;
        //SiriusClient断开事件
        public static event OnDisconnectHandler OnDisconnect;
        //用于Http请求的URL
        public static string httpUrl;

        public static bool CheckBot(string BotId,string Token,bool sandBox)
        {
            try
            {
                HttpClient httpClient = new HttpClient();
                //设置验证请求头
                httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bot", $"{BotId}.{Token}");
                //等待
                var Request = httpClient.GetAsync(isSandBox(sandBox) + "/gateway");
                //获取HTTP请求码
                int RequestCode = (int)Request.Result.StatusCode;

                return RequestCode == 200;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        public static string isSandBox(bool sandBox)
        {
            return sandBox ? "https://sandbox.api.sgroup.qq.com" : "https://api.sgroup.qq.com";
        }
        public static void InitSirius(string BotId, string Token, bool sandBox)
        {
            try
            {

                //初始化SiriusHttp
                SiriusHttp = new HttpClient();
                httpUrl = isSandBox(sandBox);
                //设置验证请求头
                SiriusHttp.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bot", $"{BotId}.{Token} ");
                //HTTP请求进行等待
                var Request = SiriusHttp.GetStringAsync(isSandBox(sandBox) + "/gateway");
                Request.Wait();
                //获取data，用于SiriusClient的连接
                JsonDocument data = JsonDocument.Parse(SiriusHttp.GetStringAsync(isSandBox(sandBox) + "/gateway").Result);
                url = new Uri(data.RootElement.GetProperty("url").ToString());
                SiriusClient = new ClientWebSocket();
                LogSuc("Server", "SiriusClient初始化成功！");
            }catch (Exception ex)
            {
                LogErr("Server", "初始化失败，请检查您的网络！"+ex.Message);
            }
        }
        public static bool SiriusLogin(string BotId,string Token,bool sandBox)
        {
            if(CheckBot(BotId,Token,sandBox))
            {
                LogSuc("Server", "Bot验证成功，正在获取用与SiriusClient连接的URI");
                InitSirius(BotId,Token,sandBox);
                return true;
            }
            else
            {
                LogErr("Server", "Bot验证失败，请检查您的BotId与Token信息！");
                return false;
            }
                
        }
        public static void SiriusClientConnect()
        {
            //是否已初始化
            if (SiriusClient == null)
                LogErr("Server", "SiriusClient未初始化");
            Task.Run(async () =>
            {
                //状态是否已连接，或正在连接
                if (SiriusClient.State == WebSocketState.Open || SiriusClient.State == WebSocketState.Connecting)
                    LogWar("Server", "SiriusClient已连接,请勿重复连接!");
                try
                {
                    //进行连接
                    var task = SiriusClient.ConnectAsync(url, CancellationToken.None);
                    task.Wait();
                    if(OnConnect != null)
                        OnConnect(SiriusClient);
                    LogSuc("Server", "SiriusClient连接成功，正在等待Hello包...");
                    SiriusClientMessage();
                }catch (Exception ex)
                {
                    LogErr("Server",".net出错，请尝试重新启动"+ex.Message);
                }
            });
        }

        public static void SiriusClientMessage()
        {
            Task.Run(async () =>
            {
                while (true)
                {
                    string message;
                    Recived(SiriusClient,out message);
                    if (OnMessage != null)
                        OnMessage(SiriusClient, message);
                }
            });
        }
    }
}